/*
*@功能：ESP32手表功能测试
*@作者：刘泽文
*@时间：2020/3/27
*/
 
//引用相关库
#include <SD.h>
#include <SPI.h>
#include <Ticker.h>
#include <TFT_eSPI.h>
#include <JPEGDecoder.h>
#include <FastLED.h>
#include "bmp1.h"
#include "bmp2.h"
#include "bmp3.h"
#include "bmp4.h"
#include "bmp5.h"
#include "bmp6.h"
 
 
#define NODEBUG 
 
#ifdef DEBUG 
#define DebugPrintln(message) Serial.println(message)
#else 
#define DebugPrintln(message)
#endif
 
#ifdef DEBUG 
#define DebugPrint(message) Serial.print(message) 
#else 
#define DebugPrint(message)
#endif
 
TFT_eSPI tft = TFT_eSPI(135, 240); // Invoke custom library
SPIClass sdSPI(HSPI);
#define SD_MISO     13
#define SD_MOSI     15
#define SD_SCLK     17
#define SD_CS       14

#define NUM_LEDS 2
CRGBArray<NUM_LEDS> leds;

int freq1 = 2000;    // 频率
int channel1 = 0;    // 通道0，共16个通道，0~15
int resolution1 = 10;   // 分辨率，取值0~20，duty最大取值为2^resolution-1

int freq2 = 2000;    // 频率
int channel2 = 1;    // 通道0，共16个通道，0~15
int resolution2 = 10;   // 分辨率，取值0~20，duty最大取值为2^resolution-1

//引脚定义
#define LED         2
#define BEEP        25
#define MOTTER      26
#define UP_KEY      39
#define M_KEY       0
#define DOWN_KEY    34
#define TIME        1000

//读按键值
#define KEYU      digitalRead(UP_KEY)
#define KEYM      digitalRead(M_KEY)
#define KEYD      digitalRead(DOWN_KEY)

Ticker KEY_ticker;

void flip();
void showImage1(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data);
void showImage2(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data);

void setup()
{
  #ifdef DEBUG 
  Serial.begin(115200);
  #endif
  DebugPrintln();
  FastLED.addLeds<NEOPIXEL,2>(leds, NUM_LEDS);

  KEY_ticker.attach_ms(1,flip);
  
  ledcSetup(channel1, freq1, resolution1); // 设置通道0
  ledcAttachPin(BEEP, channel1);  // 将通道0与引脚25连接
  ledcSetup(channel2, freq2, resolution2); // 设置通道0
  ledcAttachPin(MOTTER, channel2);  // 将通道1与引脚26连接
  ledcWrite(channel1, 0);  // 输出PWM
  ledcWrite(channel2, 0);  // 输出PWM

  pinMode(UP_KEY,INPUT);
  pinMode(M_KEY,INPUT);
  pinMode(DOWN_KEY,INPUT);

  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_WHITE);
  tft.setTextSize(1);
  tft.setTextColor(TFT_MAGENTA);
  tft.setCursor(0, 0);
  tft.setTextDatum(MC_DATUM);
  tft.setTextSize(1);
  tft.setSwapBytes(true);
  delay(100);

  for(int i = 0;i<10;i++)
  {
    leds.fadeToBlackBy(40);  
    leds[0] = CHSV(40*i,255,150);
    FastLED.show();
    delay(200);
    leds[0] = CHSV(0,255,0);
    FastLED.show();
    delay(200);
  }

  if (TFT_BL > 0) { // TFT_BL has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
     pinMode(TFT_BL, OUTPUT); // Set backlight pin to output mode
     digitalWrite(TFT_BL, LOW); // Turn backlight on. TFT_BACKLIGHT_ON has been set in the TFT_eSPI library in the User Setup file TTGO_T_Display.h
   }
  
}
 
void loop() {
 
  showImage2(0, 0, 240, 135, bmp1);
  delay(TIME);
  showImage2(0, 0, 240, 135, bmp2);
  delay(TIME);
  showImage2(0, 0, 240, 135, bmp3);
  delay(TIME);
  showImage2(0, 0, 240, 135, bmp4);
  delay(TIME);
  showImage2(0, 0, 240, 135, bmp5);
  delay(TIME);
  showImage2(0, 0, 240, 135, bmp6);
  delay(TIME);

  for(int i = 0; i < 360; i++) { 
    leds.fadeToBlackBy(40);  
    leds[0] = CHSV(i,255,100);
    delay(70);
    FastLED.show();
  }

  leds[0] = CHSV(0,255,0);
  FastLED.show();

  for(int i = 0;i<5;i++)
  {
    leds.fadeToBlackBy(40);  
    leds[0] = CHSV(40*i,255,150);
    FastLED.show();
    delay(200);
    leds[0] = CHSV(60,255,0);
    FastLED.show();
    delay(200);
  }
}

void flip()
{
  if(!KEYU)
    ledcWrite(channel1, 900);  // 输出PWM
  else
    ledcWrite(channel1, 0);  // 输出PWM
  if(!KEYM)
    ledcWrite(channel2, 900);  // 输出PWM
  else
    ledcWrite(channel2, 0);  // 输出PWM
}

#define PI_BUF_SIZE 128
void showImage1(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data){
  int32_t dx = 0;
  int32_t dy = 0;
  int32_t dw = w;
  int32_t dh = h;

  if (x < 0) { dw += x; dx = -x; x = 0; }
  if (y < 0) { dh += y; dy = -y; y = 0; }

  if (dw < 1 || dh < 1) return;

  CS_L;

  data += dx + dy * w;

  uint16_t  buffer[PI_BUF_SIZE];
  uint16_t* pix_buffer = buffer;

  tft.setWindow(x, y, x + dw - 1, y + dh - 1);

  // Work out the number whole buffers to send
  uint16_t nb = (dw * dh) / PI_BUF_SIZE;

  // Fill and send "nb" buffers to TFT
  for (int32_t i = 0; i < nb; i++) {
    for (int32_t j = 0; j < PI_BUF_SIZE; j++) {
      pix_buffer[j] = pgm_read_word(&data[i * PI_BUF_SIZE + j]);
    }
    tft.pushPixels(pix_buffer, PI_BUF_SIZE);
  }

  // Work out number of pixels not yet sent
  uint16_t np = (dw * dh) % PI_BUF_SIZE;

  // Send any partial buffer left over
  if (np) {
    for (int32_t i = 0; i < np; i++)
    {
      pix_buffer[i] = pgm_read_word(&data[nb * PI_BUF_SIZE + i]);
    }
    tft.pushPixels(pix_buffer, np);
  }

  CS_H;
}

void showImage2(int32_t x, int32_t y, int32_t w, int32_t h, const uint16_t *data){
  int32_t dx = 0;
  int32_t dy = 0;
  int32_t dw = w;
  int32_t dh = h*2;

  if (x < 0) { dw += x; dx = -x; x = 0; }
  if (y < 0) { dh += y; dy = -y; y = 0; }

  if (dw < 1 || dh < 1) return;

  CS_L;

  data += dx + dy * w;

  uint16_t  buffer[PI_BUF_SIZE];
  uint16_t* pix_buffer = buffer;
  uint16_t  high,low;

  tft.setWindow(x, y, x + dw - 1, y + dh - 1);

  // Work out the number whole buffers to send
  uint16_t nb = (dw * dh) / (2 * PI_BUF_SIZE);

  // Fill and send "nb" buffers to TFT
  for (int32_t i = 0; i < nb; i++) {
    for (int32_t j = 0; j < PI_BUF_SIZE; j++) {
      high = pgm_read_word(&data[(i * 2 * PI_BUF_SIZE) + 2 * j + 1]);
      low = pgm_read_word(&data[(i * 2 * PI_BUF_SIZE) + 2 * j ]);
      pix_buffer[j] = (high<<8)+low;
    }
    tft.pushPixels(pix_buffer, PI_BUF_SIZE);
  }

  // Work out number of pixels not yet sent
  uint16_t np = (dw * dh) % (2 * PI_BUF_SIZE);

  // Send any partial buffer left over
  if (np) {
    for (int32_t i = 0; i < np; i++)
    {
      high = pgm_read_word(&data[(nb * 2 * PI_BUF_SIZE) + 2 * i + 1]);
      low = pgm_read_word(&data[(nb * 2 * PI_BUF_SIZE) + 2 * i ]);
      pix_buffer[i] = (high<<8)+low;
    }
    tft.pushPixels(pix_buffer, np);
  }

  CS_H;
}
